package base.reflection_demo.demo_04;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *	通过反射机制，复制一个对象数据到另一个目标对象中。
 */
@Slf4j
public class ReflectDemo03 {
    public static void main(String[] args) throws Exception {
        Person zs = new Person("张三", 18, 13000.0f);
        Person copyObj = copyObj(zs);
        log.info("{}", copyObj);
    }

    public static Person copyObj(Object target) throws Exception {
        Class<Person> clazz = (Class<Person>) target.getClass();
        // 构造一个新的 Person对象 newPerson
        Person newPerson = clazz.newInstance();

        // 给 Field 设置属性值
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            String getMethodName = "get"+field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1);
            String setMethodName = "set"+field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1);
            Method getMethod = clazz.getMethod(getMethodName, null);
            Method setMethod = clazz.getMethod(setMethodName, new Class[]{field.getType()});
            // getMethod 在原对象 target上调用,获取原对象的值
            Object result = getMethod.invoke(target, null);
            // setMethod 在目标对象 newPerson上调用,给目标对象属性赋值
            setMethod.invoke(newPerson, result);
        }

        // 打印方法名,看下lombok给Person类添加了哪些方法
        //Method[] methods = clazz.getDeclaredMethods();
        Class<? extends Person> cla = newPerson.getClass();
        Method[] declaredMethods = cla.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            log.info("{}",declaredMethod.getName());
        }
        return newPerson;
    }
}